home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-03
/
cmsqb101.zip
/
CMSMOD.BAS
< prev
next >
Wrap
BASIC Source File
|
1990-06-09
|
7KB
|
305 lines
'******************************************************
'* *
'* File Name: CMSMOD.BAS *
'* *
'* Description: Contains all the source code *
'* necessary to play Creative Music *
'* System (CMS) files using a CMS *
'* compatable card (GameBlaster or *
'* SoundBlaster) and CMS driver *
'* (CMSDRV.COM). This file may be *
'* loaded as a program or a module. *
'* *
'* Requirements: CMSDRV resident in memory. *
'* Interruptx in QuickLib *
'* (i.e. QW.QLB). *
'* *
'******************************************************
DEFINT A-Z
TYPE RegTypeX
ax AS INTEGER
bx AS INTEGER
cx AS INTEGER
dx AS INTEGER
bp AS INTEGER
si AS INTEGER
di AS INTEGER
flags AS INTEGER
ds AS INTEGER
es AS INTEGER
END TYPE
DECLARE SUB CmsPlayMusic (Repeats%)
DECLARE SUB CmsVersion (version$)
DECLARE SUB CmsFindDriver (IntNum%, version$)
DECLARE SUB CmsPauseMusic ()
DECLARE SUB CmsContinueMusic ()
DECLARE SUB CmsStopMusic ()
DECLARE SUB WaitForKey (Key$)
DECLARE SUB GetFileName (FileSpec$)
DECLARE SUB GetCmsFile (FileSpec$)
DECLARE SUB OpenCmsFile (FileSpec$)
CONST False = 0, True = NOT False
DIM SHARED Reg88X AS RegTypeX
' Make all arrays DYNAMIC so the .CMS file won't get relocated
' and cause CMSDRV to lose track of it.
'$DYNAMIC
' The PlayFlag is used to synchronize the user program with the music.
DIM PlayFlag AS INTEGER
' CmsSong array is the .CMS file loaded from disc.
DIM CmsSong(0) AS STRING * 32767
CLS
' Set the default number of plays to 1.
Repeats = 1
' Call the routine that finds the driver interrupt number and version.
CmsFindDriver IntNum, version$
SELECT CASE IntNum
CASE IS = False
PRINT "CMSDRV is not installed."
END
CASE ELSE
' Users should modify these 2 lines to do what ever they want with
' the version number (i.e. check to see if it is 3.00 or greater)
' and interrupt number.
PRINT "CMSDRV Version "; version$
PRINT "CMSDRV is using interrupt &H"; HEX$(IntNum)
END SELECT
' Go get the name of the .CMS file to be played...
GetFileName FileSpec$
' ...and load it into memory.
GetCmsFile FileSpec$
' This is the main part of the program. The one shown is a mini program
' just to demonstrate how the routines are used.
DO
WaitForKey Key$
SELECT CASE Key$
CASE "T"
CmsStopMusic
CASE "P"
CmsPauseMusic
CASE "C"
CmsContinueMusic
CASE "S"
CmsPlayMusic Repeats
CASE "Q"
CmsStopMusic
END
CASE "N"
GetFileName FileSpec$
CmsStopMusic
GetCmsFile FileSpec$
END SELECT
LOOP
REM $STATIC
'This sub continues music play after a pause.
'Entry conditions:
' AH = 3
'Exit conditions:
' AX = 0 successful
' AX = 1 no song had been paused
'
SUB CmsContinueMusic
Reg88X.ax = &H300
CALL Interruptx(&H80, Reg88X, Reg88X)
END SUB
'This sub disables the CMS break function (CTRL-Keypad5)
'Entry conditions:
' AH = 5
'Exit conditions:
' None
'
SUB CmsDisableBreak
Reg88X.ax = &H500
CALL Interruptx(&H80, Reg88X, Reg88X)
END SUB
'This sub searches for the CMS driver CMSDRV.COM beginning at the INT 80h
'jump address thru INT 0BFh. When the SUB finds the string "CMSDRV" at
'offset 104h of the interrupt, the interrupt number used by CMSDRV.COM is
'returned to the main program.
'
SUB CmsFindDriver (Inter, Ver$)
CONST CMSDRV$ = "CMSDRV"
CONST MaxInter = &HBF, StartInter = &H80
RightString = False
Inter = StartInter
DO
DEF SEG = 0
SegmentLo = PEEK((Inter * 4) + 2)
SegmentHi = PEEK((Inter * 4) + 3)
Segment = SegmentHi * 256 + SegmentLo
DEF SEG = Segment
Offset = &H104
i = 1
DO
x$ = CHR$(PEEK(Offset))
IF x$ = MID$(CMSDRV$, i, 1) THEN
RightString = True
Offset = Offset + 1
i = i + 1
ELSE
RightString = False
END IF
LOOP WHILE (RightString = True) AND (i <= LEN(CMSDRV$))
IF RightString = True THEN
CmsVersion Ver$
EXIT DO
END IF
Inter = Inter + 1
LOOP WHILE (Inter <= MaxInter)
DEF SEG
IF Inter > MaxInter THEN Inter = False
END SUB
'This sub pauses the music currently playing.
'Entry conditions:
' AH = 2
'Exit conditions:
' AX = 0 successful
' AX = 1 no music was being played
'
SUB CmsPauseMusic
Reg88X.ax = &H200
CALL Interruptx(&H80, Reg88X, Reg88X)
END SUB
'This sub plays music from a .CMS music file.
'Entry conditions:
' AH = 1
' AL = number of times to play (1-255; 0 for non-play)
' ES = segment address of PLAY-FLAG
' BX = offset address of PLAY-FLAG
' CX = segment of music score (.CMS file in memory)
'Exit conditions:
' AX = 0 successful
' AX = 1 non-CMS file structure
' AX = 2 wrong COMPOSEr version
'
SUB CmsPlayMusic (Rpts)
SHARED PlayFlag AS INTEGER
SHARED CmsSong() AS STRING * 32767
Dummy& = FRE("")
PfSeg = VARSEG(PlayFlag)
PfOff = VARPTR(PlayFlag)
MSeg = VARSEG(CmsSong(0))
Reg88X.ax = &H100 + Rpts
Reg88X.es = PfSeg
Reg88X.bx = PfOff
Reg88X.cx = MSeg
CALL Interruptx(&H80, Reg88X, Reg88X)
END SUB
'This sub stops playing the current music.
'Entry conditions:
' AH = 4
'Exit conditions:
' None
'
SUB CmsStopMusic
Reg88X.ax = &H400
CALL Interruptx(&H80, Reg88X, Reg88X)
END SUB
' This sub gets the the version number of the .CMS driver and returns
' it as Ver$.
'
SUB CmsVersion (Ver$)
Reg88X.ax = 0
CALL Interruptx(&H80, Reg88X, Reg88X)
SELECT CASE LEN(HEX$(Reg88X.ax))
CASE IS = 3
Ver$ = LEFT$(HEX$(Reg88X.ax), 1) + "." + RIGHT$(HEX$(Reg88X.ax), 2)
CASE IS = 4
Ver$ = LEFT$(HEX$(Reg88X.ax), 2) + "." + RIGHT$(HEX$(Reg88X.ax), 2)
END SELECT
END SUB
' This routine loads a .CMS file (FSpec$) from disc
' into CmsSong array.
'
SUB GetCmsFile (FSpec$)
SHARED CmsSong() AS STRING * 32767
OPEN FSpec$ FOR BINARY AS #1
GET #1, , CmsSong(0)
CLOSE #1
END SUB
SUB GetFileName (FileSpec$)
GoodFile = True
LOCATE 3, 1
PRINT SPACE$(79)
LOCATE 10, 1
INPUT "Which drive and path"; Drive$
FILES Drive$ + "*.cms"
DO
LOCATE 3, 1
LINE INPUT "Enter CMS file name: "; FileSpec$
LOOP WHILE GoodFile = False
FileSpec$ = Drive$ + FileSpec$
END SUB
SUB WaitForKey (K$)
LOCATE 5, 1
PRINT "N)ew file, S)tart, C)ontinue, P)ause, T)erminate, Q)uit: ";
DO
K$ = INKEY$
LOOP WHILE K$ = ""
K$ = UCASE$(K$)
PRINT K$;
END SUB